package org.nf.web.embed.servlet;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ClassUtil;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import org.nf.web.config.Configure;

import java.io.File;

/**
 * @Author lzp
 * @Date 2024-05-13
 * Tomcat容器
 */
public class TomcatServet extends AbstractWebServlet{

    @Override
    public void start(Configure configure) throws Exception{
        //实例化Tomcat对象
        Tomcat tomcat = new Tomcat();
        //设置端口
        tomcat.setPort(configure.getServet().getPort());
        //将webRoot构件为绝对路径
        String webRoot =configure.getServet().getWebRoot();
        webRoot = FileUtil.getWebRoot().getAbsolutePath() + File.separator + webRoot;
        //设置contextPath和web资源目录，并返回一个Context上下文对象
        Context context = tomcat.addWebapp(configure.getServet().getContextPath(), webRoot);
        //设置应用程序的编译路径，这样web容器启动时会从 classpath路径下查找带有Servlet注解的组件
        //列如：@WebServlet、@WebFilter、@WebListener
        WebResourceRoot resourceRoot = new StandardRoot(context);
        //构件DirResourceSet对象
        DirResourceSet resourceSet =new DirResourceSet(resourceRoot,
                "/WEB-INF/classes",
                ClassUtil.getClassPath(),"/");

        resourceRoot.addPreResources(resourceSet);
        //再将 resourceRoot加入到Context上下文
        context.setResources(resourceRoot);

        //获取ServletContext对象,并将配置对象保存到上下文便于在DispatcherServlet中获取
        context.getServletContext().setAttribute("configure",configure);

        //创建连接
        tomcat.getConnector();
        //启动tomcat
        try {
            tomcat.start();
            //将tomcat进行阻塞，保持运行状态
            tomcat.getServer().await();
        } catch (LifecycleException e) {
            throw new RuntimeException("Start tomcat fail.",e);
        }
    }


}
